﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Castle.ActiveRecord.Framework;
using Castle.ActiveRecord;
using Castle.ActiveRecord.Framework.Config;
using System.Reflection;
using Matriculex.Dominio;
using System.Diagnostics;

namespace Matriculex.Testes
{
    /// <summary>
    /// Summary description for TesteActiveRecord
    /// </summary>
    [TestClass]
    public class TesteActiveRecord
    {
        public TesteActiveRecord()
        {
        }
        private TestContext testContextInstance;
        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        [ClassInitialize()]
        public static void MyClassInitialize(TestContext testContext)
        {
        }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        [TestInitialize()]
        public void MyTestInitialize()
        {
            ActiveRecordSQLLiteConnectionProvider.InitializeActiveRecord();
        }
        //
        // Use TestCleanup to run code after each test has run
        [TestCleanup()]
        public void MyClassCleanup()
        {
            ActiveRecordSQLLiteConnectionProvider.ExplicitlyDestroyConnection();
        }
        //
        #endregion

        [TestMethod]
        public void CriaUsuárioSemNome()
        {
            try
            {
                AlunoAberto semNome = new AlunoAberto("semNome", "a", "semNome", null);
                semNome.Save();
                //se o assert estiver lah dentro e nao der excecao, o teste vai passar
                Assert.Fail("Foi possível salvar aluno sem nome!");
            }
            catch (AssertFailedException) { throw; }
            catch (Exception) { }
            finally {
              //  Assert.AreEqual(0, AlunoAberto.FindAll().Length, "Criou usuario sem nome!");
            }
           
        }
        

        [TestMethod]
        public void CriaUsuário()
        {
            Gerente gerente = new Gerente("paul mccartney", "paul");
            gerente.SetSenha("paul123");
            gerente.Save();

            AlunoAberto al1 = new AlunoAberto("12345", "john lennon","john", null );
            al1.SetSenha("senha");
            al1.Save();

            AlunoFechado al2 = new AlunoFechado("54321", "john", "john lennon", null);
            al2.SetSenha("senha");
            al2.Save();

            try
            {
                AlunoAberto semEmail = new AlunoAberto("semEmail", "semEmail", "", null);
                semEmail.Save();
                Assert.Fail("Foi possível salvar aluno sem email!");
            }
            catch (AssertFailedException) { throw; }
            catch (Exception) { }

            try
            {
                AlunoAberto semNumeroPece = new AlunoAberto("", "semNumeroPece", "semNumeroPece", null);
                semNumeroPece.Save();
                Assert.Fail("Foi possível salvar aluno sem No. PECE!");
            }
            catch (AssertFailedException) { throw; }
            catch (Exception) { }

            var gerentes = Gerente.FindAll();
            var alunosAbertos = AlunoAberto.FindAll();
            var alunosFechados = AlunoFechado.FindAll();

            Assert.AreEqual(1, gerentes.Length);
            Assert.AreEqual("paul", gerentes[0].Email);
            Assert.AreEqual(1, alunosAbertos.Length);
            Assert.AreEqual("12345", alunosAbertos[0].NumeroPECE);
            Assert.AreEqual(1, alunosFechados.Length);
            Assert.AreEqual("54321", alunosFechados[0].NumeroPECE);
        }

        [TestMethod]
        public void CriaCurso()
        {
            CursoAberto c1 = new CursoAberto("Lógica", "PCS1234", 14);
            c1.Save();

            CursoFechado c2 = new CursoFechado("Lógica II", "PCS4321", 14);
            c2.Save();

            var abertos = CursoAberto.FindAll();
            var fechados = CursoFechado.FindAll();

            Assert.AreEqual(2, Curso.FindAll().Length);
            Assert.AreEqual(1, abertos.Length);
            Assert.AreEqual("PCS1234", abertos[0].Código);
            Assert.AreEqual(1, fechados.Length);
            Assert.AreEqual("PCS4321", fechados[0].Código);
        }

        [TestMethod]
        public void CriaDisciplina()
        {
            Disciplina disc = new Disciplina("1234", "123");
            disc.Save();

            var disciplinas = Disciplina.FindAll();
            Assert.AreEqual(1, disciplinas.Length);
            Assert.AreEqual("1234", disciplinas[0].Código);
        }


        [TestMethod]
        public void CriaDisciplinaDuplicada()
        {
            Disciplina disc = new Disciplina("1234", "123");
            disc.Save();

            try
            {
                disc = new Disciplina("1234", "Nova");
                disc.Save();
                Assert.Fail();
            }
            catch (AssertFailedException) { throw; }
            catch (Exception) { }

            var disciplinas = Disciplina.FindAll();

            Assert.AreEqual(1, disciplinas.Length);
            Assert.AreEqual("1234", disciplinas[0].Código);
            Assert.AreEqual("123", disciplinas[0].Nome);

            disciplinas[0].Nome = "Nova";
            disciplinas[0].Save();

            disciplinas = Disciplina.FindAll();
            Assert.AreEqual(1, disciplinas.Length);
            Assert.AreEqual("1234", disciplinas[0].Código);
            Assert.AreEqual("Nova", disciplinas[0].Nome);


        }




        [TestMethod]
        public void AssociaCursoDisciplina()
        {
            CriaCurso();
            CriaDisciplina();

            CursoAberto c = CursoAberto.FindAll()[0];
            Disciplina d = Disciplina.FindAll()[0];
            c.Disciplinas.Add(d); // OK
            c.Save();

            Assert.AreEqual("1234", CursoAberto.FindAll()[0].Disciplinas[0].Código);
            Assert.AreEqual("PCS1234", Disciplina.FindAll()[0].Cursos[0].Código);

            c.Disciplinas.RemoveAt(0);
            c.Save();
            Assert.AreEqual(0, Disciplina.FindAll()[0].Cursos.Count);

            try
            {
                d.Cursos.Add(c); // nao pode (inverse=true)
                Assert.Fail();
            }
            catch (AssertFailedException) { throw; }
            catch (Exception) { }
        }

        [TestMethod]
        public void Autentica()
        {
            CriaUsuário();
            Assert.AreEqual("paul", Usuario.Autentica("paul", "paul123").Email);
        }

        [TestMethod]
        public void AlunoAbertoDisciplina()
        {
            CriaUsuário();
            CriaDisciplina();
            var aberto = AlunoAberto.FindAll()[0];
            var d = Disciplina.FindAll()[0];
            aberto.DisciplinasPreSelecionadas.Add(d);
            aberto.Save();
            // verifica
            Assert.AreEqual<int>(aberto.Id, Disciplina.FindAll()[0].AlunosPreInscritos[0].Id);
            Assert.AreEqual<int>(d.Id, AlunoAberto.FindAll()[0].DisciplinasPreSelecionadas[0].Id);
        }
    }
}
